#include "Head.h"

// 链表初始化
Flight_Head_Node *Init_dlist()
{
    Flight_Head_Node *Head = NULL;

    // 创建动态空间
    Head = (Flight_Head_Node *)malloc(sizeof(Flight_Head_Node));

    // 安全判断
    if (Head == NULL)
    {
        printf("链表创建失败!\n");
        return NULL;
    }

    Head->next = NULL;

    return Head;
}

// 链表销毁
void Free_dlist(Flight_Head_Node **Head)
{
    // 安全判断
    if (*Head == NULL)
    {
        ERRLOG("链表为NULL");
        return;
    }
    if ((*Head)->next == NULL)
    {
        ERRLOG("链表为空");

        // 链表没数据直接 释放 头节点
        (*Head)->next = NULL;
        free(*Head);
        return;
    }

    Flight_Node *ptr_1 = (*Head)->next;
    Flight_Node *ptr_2 = ptr_1->next;

    // 销毁节点

    // 因为此时 ptr_1->next == (*Head)->next 所以先执行一次
    do
    {
        free(ptr_1);
        ptr_1 = ptr_2;
        if (ptr_2->next != (*Head)->next) // 当ptr_2->next == (*Head)->next 时 ptr_2不往下跳了
        {
            ptr_2 = ptr_2->next;
        }

    } while (ptr_1->next != (*Head)->next); // ptr_1->next == (*Head)->next 时结束循环

    // 销毁头节点
    (*Head)->next = NULL;
    free(*Head);
}

// 链表插入
void Insert_dlist(Flight_Head_Node *Head, Flight_data data, int pos)
{
    // 安全判断
    if (Head == NULL)
    {
        ERRLOG("链表为NULL");
    }

    // 创建下一个节点的地址
    Flight_Node *New_Node = (Flight_Node *)malloc(sizeof(Flight_Node));

    // ptr 指向 头节点的next
    Flight_Node *ptr = Head->next;

    // 为下一个节点添加数据域 , 指针域
    New_Node->data = data;
    // 新节点的前驱/后继指向自己
    New_Node->next = New_Node;
    New_Node->prev = New_Node;

    // 头插
    if (pos == 1 || Head->next == NULL)
    {
        // 无数据头插
        if (pos == 1 && Head->next == NULL)
        {
            // 头节点指向新节点地址
            Head->next = New_Node;
            return;
        }
        // 有数据头插
        if (Head->next != NULL)
        {
            // ptr的前驱(尾节点) 的后继 指向 新节点
            ptr->prev->next = New_Node;
            // 新节点的前驱 指向 尾节点
            New_Node->prev = ptr->prev;
            // 新节点的后继 指向 ptr的后继
            New_Node->next = ptr->next;
            // 新节点 的后继 指向 头节点的后继
            New_Node->next = Head->next;
            // 头节点的后继 指向 新节点
            Head->next = New_Node;
            return;
        }
    }
    // 任意插
    for (size_t i = 1; i < pos - 1; i++) // 遍历到 pos 前一个节点
    {
        ptr = ptr->next;
    }
    // 新节点的后继 指向 ptr的后继
    New_Node->next = ptr->next;
    // ptr 的后继 的前驱 指向 新节点
    ptr->next->prev = New_Node;
    // ptr 的后继 指向 新节点
    ptr->next = New_Node;
    // 新节点 的前驱 指向 ptr
    New_Node->prev = ptr;
    return;
}

// 链表删除
void Del_dlist(Flight_Head_Node *Head, int pos)
{
    // 安全判断
    if (NULL == Head)
    {
        ERRLOG("双向循环链表 为 NULL");
        return;
    }
    if (NULL == Head->next)
    {
        ERRLOG("双向循环链表 为 NULL");
        return;
    }

    // 删除
    Flight_Node *ptr_1 = Head->next;
    Flight_Node *ptr_2 = ptr_1->next;

    // 头删  情况 1、 pos == 1  2、只有一个元素  ptr_1->next == Head->nexts
    if (1 == pos || ptr_1->next == Head->next)
    {
        // 只有一个结点数据的时候
        if (ptr_1->next == Head->next)
        {
            free(Head->next);
            Head->next = NULL;
            // 写入文件
            File_Printf_Flight(Head);
            return;
        }
        // 多个结点数据删第一个
        if (1 == pos)
        {
            // 1、 将头结点 指向 第二个 结点
            Head->next = ptr_2;
            // 2、 将 ptr2 指向 尾结点
            ptr_2->prev = ptr_1->prev;
            // 3、 将尾结点 的 指向 第二个结点
            ptr_1->prev->next = ptr_2;
            // 4、 释放 ptr 1
            free(ptr_1);
            // 写入文件
            File_Printf_Flight(Head);

            return;
        }
    }
    // 任意位置删除
    for (size_t i = 1; i < pos - 1; i++) // 遍历到 pos 前一个节点
    {
        ptr_1 = ptr_1->next;
    }
    // ptr_2 指向 pos 的位置 储存要删除节点的信息
    ptr_2 = ptr_1->next;
    // ptr_1 的后继 指向 ptr_2 的后继
    ptr_1->next = ptr_2->next;
    // ptr_2 的后继的前驱 指向 ptr_1
    ptr_2->next->prev = ptr_1;
    // 释放 ptr_2
    free(ptr_2);
    // 写入文件
    File_Printf_Flight(Head);

    return;
}

// 链表遍历 打印所有航班信息
void Print_dlist(Flight_Head_Node *Head)
{
    // 安全判断
    if (Head == NULL)
    {
        ERRLOG("双向循环链表为NULL");
        return;
    }
    if (Head->next == NULL)
    {
        ERRLOG("暂无任何航班信息 , 尽请期待");
        return;
    }

    // 创建 航班节点指针 用于遍历
    Flight_Node *ptr = Head->next;

    printf("__________________________________________________________________________________________________________________________________________________\n");
    printf("航班班次\t飞机机型\t起点站\t终点站\t起飞时间\t到达时间\t飞行时间\t票价\t额定载客量\t剩余座位数\t是否起飞\n");
    printf("——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————\n");

    do
    {
        if (ptr->data.whetherfly == 'y') // 起飞红色
        {
            printf("\33[1m\33[31m  %-10d\t%-10s\t%-10s%-10s%-d : %d\t\t%d : %d\t\t%-10s\t%-10d%-5d\t\t  %d\t\t  %-8c\n\33[0m",
                   /*航班                  飞机机型                 航班起点站                    航班终点站*/
                   ptr->data.id, ptr->data.flighttype, ptr->data.startcity, ptr->data.arrivecity,
                   /*起飞时间 时            起飞时间 分              到达时间 时                   到达时间 分*/
                   ptr->data.starttime[0], ptr->data.starttime[1], ptr->data.arrivetime[0], ptr->data.arrivetime[1],
                   /*飞行时间               票价                    额定载客量                    剩余座位数*/
                   ptr->data.flytime, ptr->data.value, ptr->data.maxNUM, ptr->data.leftbuyersa,
                   /*是否起飞*/
                   ptr->data.whetherfly);
            printf("——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————\n");
        }
        if (ptr->data.whetherfly == 'n') // 待机绿色
        {
            printf("\33[1m\33[32m  %-10d\t%-10s\t%-10s%-10s%-d : %d\t\t%d : %d\t\t%-10s\t%-10d%-5d\t\t  %d\t\t  %-8c\n\33[0m",
                   /*航班                  飞机机型                 航班起点站                    航班终点站*/
                   ptr->data.id, ptr->data.flighttype, ptr->data.startcity, ptr->data.arrivecity,
                   /*起飞时间 时            起飞时间 分              到达时间 时                   到达时间 分*/
                   ptr->data.starttime[0], ptr->data.starttime[1], ptr->data.arrivetime[0], ptr->data.arrivetime[1],
                   /*飞行时间               票价                    额定载客量                    剩余座位数*/
                   ptr->data.flytime, ptr->data.value, ptr->data.maxNUM, ptr->data.leftbuyersa,
                   /*是否起飞*/
                   ptr->data.whetherfly);
            printf("——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————\n");
        }

        ptr = ptr->next; // 指向下一个节点
    } while (ptr != Head->next);
}

// 链表查找 航班班次 返回该航班信息
Flight_Node *Find_by_id(Flight_Head_Node *Head, int id)
{
    // 安全判断
    if (Head == NULL)
    {
        ERRLOG("双向循环链表为NULL");
        return NULL;
    }
    if (Head->next == NULL)
    {
        ERRLOG("啥也没有,找个集贸");
        return NULL;
    }

    // 创建 航班节点指针 用于遍历
    Flight_Node *ptr = Head->next;

    // 查找有无该航班信息
    do
    {
        if (ptr->data.id == id)
        {
            return ptr; // 返回该航班信息
        }

        ptr = ptr->next; // 指向下一个节点

    } while (ptr != Head->next);
    return NULL;
}

// 链表查找 航班目的地 输出所有符合的航班信息
Flight_Node *Find_by_arrive(Flight_Head_Node *Head, char *arrive)
{
    // 安全判断
    if (Head == NULL)
    {
        ERRLOG("双向循环链表为NULL");
        return NULL;
    }
    if (Head->next == NULL)
    {
        ERRLOG("啥也没有,找个集贸");
        return NULL;
    }
    // 创建 航班节点指针 用于遍历
    Flight_Node *ptr = Head->next;
    // 判断是否找到 符合的航班
    int flog = 0;
    // 查找有无该航班信息
    do
    {
        if (!strcmp(ptr->data.arrivecity, arrive))
        {
            return ptr;
            flog = 1;
        }
        ptr = ptr->next; // 指向下一个节点

    } while (ptr != Head->next);

    if (flog != 1)
    {
        printf("该航班信息不存在\n");
    }
    return NULL;
}

// 链表清空
void Empty_dlist(Flight_Head_Node *Head)
{
    // 安全判断
    if (Head == NULL)
    {
        ERRLOG("双向循环链表为NULL");
        return;
    }
    if (Head->next == NULL)
    {
        // ERRLOG("链表为空");

        // 链表没数据 则直接返回
        return;
    }

    Flight_Node *ptr_1 = Head->next;
    Flight_Node *ptr_2 = ptr_1->next;

    // 销毁节点
    // 因为此时 ptr_1 == Head->next 所以先执行一次

    do
    {
        free(ptr_1);
        ptr_1 = ptr_2;
        if (ptr_2->next != Head->next) // 当ptr_2->next == Head->next 时 ptr_2不往下跳了
        {
            ptr_2 = ptr_2->next;
        }

    } while (ptr_1->next != Head->next); // ptr_1->next == Head->next 时结束循环
    Head->next = NULL;

    return;
}
